# -*- coding: utf-8 -*-
from functools import wraps
import datetime
import random
import logging
import re
import StringIO
import urllib2
import sys

from flask import *
from werkzeug.datastructures import MultiDict
import gevent
from pymongo import MongoClient, DESCENDING

import forms

try:
    import setting
    import ajax
except ImportError:
    sys.path.append('..')
    import setting
    import ajax

if '../..' not in sys.path: sys.path.append('../..')
from core.tools import getDistance, timeHandle, FamilyPush, sendMail, json, SchedulerSilent_on, SchedulerSilent_off
from core.packet import interact, sendtodev, reduceAudio, findimei
from core.jobs import addScheduler, delScheduler, WeekDay
from core import model
from core.model import User, Device, UserDev, Maprecord, Apprecord, Saferegion, DevData, Authresult, Silent, \
    StarAward, StepAward, Disauth, Feedback, UserDevRelate, Message, DeviceAudio, \
    MessageCenter, getuserdevRelate, Loger
from core.cache import redis
from agent.alphabet import OK, NO, TIMEOUT

api = Blueprint('api', __name__, static_folder='static', template_folder='templates')
logger = logging.getLogger('web')

if setting.db['username'] and setting.db['password']:
    db = MongoClient(
        'mongodb://' + setting.db['username'] + ':' + setting.db['password'] + '@' + setting.db['host'])
else:
    db = MongoClient()


class NoDevData():
    """
    宝贝没有数据时,返回各个数据项为0
    用对象方便使用统一的属性方式返回数据
    """

    target = 0
    award = ''
    star = 0
    step = 0
    distance = 0
    calories = 0
    address = ''
    lat = 0
    lon = 0
    time = datetime.datetime.min
    useGPS = False


def environmentSetup():
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                logger.error('error in %s:%r %r' % (func.__name__, args, kwargs), exc_info=True)
                return ajax.failed(ajax.serverno)

        return wrapper

    return decorator


def validate_form(forms):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                form = MultiDict(request.json) if request.json else request.form if request.form else MultiDict(
                    eval(request.data)) if request.data else MultiDict()
                # 当werkzeug不能解析Content-Type头部时
                # 所有原始字符串放在request.data中
                # 当Content-Type:application/json
                # 数据为json格式且能够解析时,数据在request.json中
                # 以post方式传参时,参数在request.form中
            except:
                logger.error('error in %s' % (func.__name__,), exc_info=True)
                return ajax.failed(ajax.jsonno)
            g.form = forms(form)
            if g.form.validate():
                return func(*args, **kwargs)
            else:
                return ajax.failed(ajax.params_error)

        return wrapper

    return decorator


@api.route('/regist', methods=['POST'])
@validate_form(forms.regist)
@environmentSetup()
def regist():
    if not ((g.form.phone.data and g.form.password.data) or g.form.token.data):
        return ajax.failed(ajax.params_error)
    user = User.objects(phone=g.form.phone.data, email__in=(None,)).only('id', 'password', 'token').first()
    if not user:
        u = User.objects().only('id').order_by('-id').first()
        uid = u.id + 1 if u else 1
        user = User(
            id=uid,
            phone=g.form.phone.data,
            password=g.form.password.data,
            token=g.form.token.data
        )
        user.save()
        return ajax.succed(ajax.ok, {'userid': user.id, 'havingbaby': 0})
    user.password = g.form.password.data
    user.token = g.form.token.data
    user.save()
    k = 1 if UserDev.objects(user=user).first() else 0
    if user.password == g.form.password.data:
        return ajax.succed(ajax.userexist, {'userid': user.id, 'havingbaby': k})
    else:
        return ajax.succed(ajax.userupdate, {'userid': user.id, 'havingbaby': k})


@api.route('/authcode', methods=['POST'])
@validate_form(forms.phone)
@environmentSetup()
def authcode():
    try:
        int(g.form.data['phone'])
    except ValueError:
        return ajax.failed(ajax.params_error)
    code = str(random.randint(100000, 999999))
    resolve = urllib2.urlopen('http://v.juhe.cn/sms/send?mobile=' + g.form.data[
        'phone'] + '&tpl_id=1&tpl_value=%23code%23%3D' + code + '%26%23company%23%3D%E5%84%BF%E7%AB%A5%E8%85%95%E8%A1%A8&key=1663924b281be6d292f68fba413a67cf').read()
    result = json.loads(resolve)
    if result['error_code'] != 0:
        logger.error('Juhe sms failed:' + resolve)
        return ajax.failed(ajax.notesendno, {'code': result['error_code']})
    return ajax.succed(ajax.ok, {'code': code})


@api.route('/email_regist', methods=['POST'])
@validate_form(forms.email_regist)
@environmentSetup()
def email_regist():
    try:
        User.objects(email=g.form.email.data).get()
        return ajax.failed(ajax.emailconflict)
    except User.DoesNotExist:
        u = User.objects().only('id').order_by('-id').first()
        uid = u.id + 1 if u else 1
        user = User(
            id=uid,
            email=g.form.email.data,
            password=g.form.password.data,
            token=g.form.token.data
        )
        user.save()
        return ajax.succed(ajax.ok, {'userid': user.id, 'havingbaby': 0})


@api.route('/ifregist', methods=['POST'])
@validate_form(forms.phone)
@environmentSetup()
def ifregist():
    try:
        User.objects(phone=g.form.phone.data).get()
        status = 'yes'
    except User.DoesNotExist:
        status = 'no'
    return ajax.succed(ajax.ok, {'status': status})


@api.route('/if_email_regist', methods=['POST'])
@validate_form(forms.email)
@environmentSetup()
def if_email_regist():
    try:
        User.objects(email=g.form.email.data).get()
        status = 'yes'
    except User.DoesNotExist:
        status = 'no'
    return ajax.succed(ajax.ok, {'status': status})


@api.route('/bindtoken', methods=['POST'])
@validate_form(forms.bindtoken)
@environmentSetup()
def bindtoken():
    try:
        user = User.objects(id=g.form.userid.data).get()
        user.token = g.form.token.data
        user.save()
        return ajax.succed(ajax.ok)
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)


@api.route('/binddevicetoken', methods=['POST'])
@validate_form(forms.BindDeviceToken)
@environmentSetup()
def binddevicetoken():
    try:
        if g.form.data['token']:
            redis.hmset('User:' + str(g.form.data['userid']), {
                'appletoken': g.form.data['token'],
                'version': g.form.data['version'],
            })
        else:
            redis.hdel('User:' + str(g.form.data['userid']), 'appletoken')
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    return ajax.succed(ajax.ok)


@api.route('/login', methods=['POST'])
@validate_form(forms.login)
@environmentSetup()
def login():
    phone = g.form.phone.data
    password = g.form.password.data
    token = g.form.token.data
    email = g.form.email.data
    if email and not re.match('^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$', email):
        return ajax.failed(ajax.params_error)
    logintype = g.form.logintype.data
    if logintype == '1':
        if not phone:
            return ajax.failed(ajax.phoneno)
        user = User.objects(phone=phone, email__in=(None,)).first()
        if not user:
            return ajax.failed(ajax.phoneno)
        if password == user.password:
            pass
            # 用户验证结束
        else:
            return ajax.failed(ajax.passno)
    elif logintype == '2':
        try:
            if not token:
                raise User.DoesNotExist
            else:
                user = User.objects(token=token).first()
                if not user:
                    raise User.DoesNotExist
                    # 用户验证结束
        except User.DoesNotExist:
            return ajax.failed(ajax.tokenno)
    else:
        if not email:
            return ajax.failed(ajax.params_error)
        try:
            if not email:
                raise User.DoesNotExist
            user = User.objects(email=email).get()
        except User.DoesNotExist:
            return ajax.failed(ajax.emailno)
        if password == user.password:
            pass
            # 用户验证结束
        else:
            return ajax.failed(ajax.passno)
    user.lasttime = datetime.datetime.now()
    user.model = g.form.model.data if g.form.model.data else ''
    k = UserDev.objects(user=user).first()
    k = 1 if k else 0
    authlist = []
    authresult = []
    authing = []
    if k:
        # 用户有宝贝
        for i in Disauth.objects(admin=user):
            authlist.append({
                'userid': i.user.id,
                'imei': i.dev.imei,
                'phone': i.userphone,
                'relate': i.relate.value,
                'time': i.time
            })
    else:
        # 用户没有宝贝
        for i in Disauth.objects(user=user):
            authing.append({
                'imei': i.dev.imei,
                'admin': i.admin.id,
                'phone': i.adminphone
            })
    for i in user.authresult:
        try:
            authresult.append({
                'imei': i.dev.imei,
                'result': i.result,
                'time': i.time
            })
        except:
            pass
    user.authresult = []
    user.save()
    adminphone = user.phone if user.admin == user.id else ''
    if user.admin and user.admin != user.id:
        try:
            admin = User.objects(id=user.admin).only('phone').get()
            adminphone = admin.phone
        except User.DoesNotExist:
            adminphone = ''
            logger.error('user not have admin', exc_info=True)
    return ajax.succed(ajax.ok, {
        'userid': user.id,
        'phone': user.phone,
        'adminphone': adminphone,
        'havingbaby': k,
        'portrait': '',
        'authresult': authresult,
        'authlist': authlist,
        'authing': authing
    })


@api.route('/modifypassword', methods=['POST'])
@validate_form(forms.modifypassword)
@environmentSetup()
def modifypassword():
    try:
        user = User.objects(id=g.form.userid.data).only('password').get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    if g.form.oldpassword.data == user.password:
        user.password = g.form.newpassword.data
        user.save()
        return ajax.succed(ajax.ok)
    else:
        return ajax.failed(ajax.nopass)


@api.route('/forgetpassword', methods=['POST'])
@validate_form(forms.forgetpassword)
@environmentSetup()
def forgetpassword():
    try:
        user = User.objects(id=g.form.userid.data).only('password').get()
        user.password = g.form.password.data
        user.save()
        return ajax.succed(ajax.ok)
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)


@api.route('/forget_email_password', methods=['POST'])
@validate_form(forms.email)
@environmentSetup()
def forget_email_password():
    try:
        user = User.objects(email=g.form.email.data).only('password').get()
        sendMail(
            g.form.email.data,
            'This is Your Old Password',
            'Please save your password:' + user.password,
        )
        return ajax.succed(ajax.ok)
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)


@api.route('/userportrait', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def userportrait():
    try:
        user = User.objects(id=g.form.userid.data).only('id', 'relateInfo').get()
        return ajax.succed(ajax.ok, {'portrait': user.portrait})
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)


@api.route('/babyrelatelist', methods=['POST'])
def babyrelatelist():
    if model.relatewrite >= model.relateread:
        model.updateUserDevRelate()
    return ajax.succed(ajax.ok, model.userdevRelateList)


@api.route('/baby', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def baby():
    userid = g.form.userid.data
    try:
        user = User.objects(id=userid).only('admin').get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    result = UserDev.objects(user=user.admin)
    if not result:
        return ajax.failed(ajax.familyno)
    babylist = []
    family_dev = [ud.dev for ud in result]
    my_relate = {ud.dev.imei: ud.relate for ud in UserDev.objects(user=userid, dev__in=family_dev)}
    for ud in result:
        relate = my_relate[ud.dev.imei].value if ud.dev.imei in my_relate else 'family'
        babylist.append({
            'imei': ud.dev.imei,
            'name': ud.dev.name,
            'phone': ud.dev.phone,
            'relate': relate,
            'portrait': ud.dev.portrait,
            'addtime': ud.time
        })
    return ajax.succed(ajax.ok, babylist)


@api.route('/familyrelatelist', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def familyrelatelist():
    if model.relatewrite >= model.relateread:
        model.updateUserDevRelate()
    try:
        dev = Device.objects(imei=g.form.imei.data).only('family').get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    familyrelateList = getuserdevRelate()
    if dev.family:
        for user in User.objects(id__in=dev.family):
            if user.relateInfo in familyrelateList:
                try:
                    familyrelateList.pop(user.relateInfo)
                except KeyError:
                    pass
    return ajax.succed(ajax.ok, familyrelateList)


@api.route('/ifaddbaby', methods=['POST'])
@validate_form(forms.userbaby)
@environmentSetup()
def ifaddbaby():
    userid = g.form.userid.data
    imei = g.form.imei.data
    try:
        user = User.objects(id=userid).get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    try:
        dev = Device.objects(imei=imei).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    try:
        MyUserDev = UserDev.objects(dev=dev, user=user).get()
        # 用户与宝贝已有关系
        if MyUserDev.type != 'admin':
            # 用户为普通成员
            return ajax.succed(ajax.needadmin, {'status': 'no'})
        else:
            return ajax.succed(ajax.hasown, {'status': 'isok'})
    except UserDev.DoesNotExist:
        pass
    u_is_admin = UserDev.objects(user=user, type='admin').first()
    u_has_family = UserDev.objects(user=user).first()
    dev_has_family = UserDev.objects(dev=dev, type='admin').first()
    if dev_has_family:
        # 宝贝有管理员
        if u_is_admin:
            # 用户为管理员
            return ajax.succed(ajax.hasadmin,
                               {'admin': dev_has_family.user.id, 'phone': dev_has_family.phone, 'status': 'isno'})
        elif u_has_family:
            # 用户为普通用户
            return ajax.succed(ajax.needadmin, {'status': 'no'})
        else:
            # 用户为新用户
            admin = dev_has_family.user
            return ajax.succed(ajax.needauth, {
                'admin': admin.id,
                'phone': admin.phone,
                'babyname': dev.name,
                'babyphone': dev.phone,
                'status': 'ok',
            })
    else:
        # 宝贝没有管理员
        if u_has_family and not u_is_admin:
            # 用户为普通用户
            return ajax.succed(ajax.needadmin, {'status': 'no'})
        return ajax.succed(ajax.ok, {'status': 'isok'})


@api.route('/tryaddbaby', methods=['POST'])
@validate_form(forms.userbaby)
@environmentSetup()
def tryaddbaby():
    userid = g.form.userid.data
    imei = g.form.imei.data
    try:
        user = User.objects(id=userid).get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    try:
        dev = Device.objects(imei=imei).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    try:
        MyUserDev = UserDev.objects(dev=dev, user=user).get()
        # 用户与宝贝已有关系
        if MyUserDev.type != 'admin':
            # 用户为普通成员
            return ajax.succed(ajax.needadmin, {'status': 'no'})
        else:
            return ajax.succed(ajax.hasown, {'status': 'isok'})
    except UserDev.DoesNotExist:
        pass
    u_is_admin = UserDev.objects(user=user, type='admin').first()
    u_has_family = UserDev.objects(user=user).first()
    dev_has_family = UserDev.objects(dev=dev, type='admin').first()
    if dev_has_family:
        # 宝贝有管理员
        if u_is_admin:
            # 用户为管理员
            return ajax.succed(ajax.hasadmin,
                               {'admin': dev_has_family.user.id, 'phone': dev_has_family.user.phone, 'status': 'isno'})
        elif u_has_family:
            # 用户为普通用户
            return ajax.succed(ajax.needadmin, {'status': 'no'})
        else:
            # 用户为新用户
            admin = dev_has_family.user
            return ajax.succed(ajax.needauth, {
                'admin': admin.id,
                'phone': admin.phone,
                'babyname': dev.name,
                'babyphone': dev.phone,
                'status': 'ok',
            })
    else:
        # 宝贝没有管理员
        if u_has_family and not u_is_admin:
            # 用户为普通用户
            return ajax.succed(ajax.needadmin, {'status': 'no'})
        # 不需腕表确认,但需要腕表在线
        if not findimei(imei):
            diff = datetime.datetime.now() - dev.lasttime
            if diff.seconds < 300:
                gevent.spawn(SendAddBabyOk, userid)
            else:
                return ajax.failed(ajax.offline)
        gevent.spawn(SendAddBabyOk, userid)
        return ajax.succed(ajax.ok, {'status': 'isok'})


def SendAddBabyOk(userid):
    gevent.sleep(3)
    FamilyPush([userid], {'type': 'babyauthok'})


def UpdateDeviceInfo(dev, portrait, name, age, height, weight, sex, steplen, babyphone, birthday):
    k = 0
    if portrait:
        dev.updatePortrait(portrait)
        k = 1
    if name:
        dev.name = name.replace(',', '')
        k = 1
    if age:
        dev.age = age
        k = 1
    if height:
        dev.height = height
        k = 1
    if weight:
        dev.weight = weight
        k = 1
    if sex:
        dev.sex = sex
        k = 1
    if steplen:
        dev.steplen = steplen
        k = 1
    if babyphone:
        dev.phone = babyphone
        k = 1
    if birthday:
        dev.birthday = birthday
    if k == 1:
        dev.modified = 1
        dev.save()
        sex = '1' if dev.sex == 'boy' else setting.default['sex']
        age = str(dev.age) if dev.age else setting.default['age']
        height = str(dev.height) if dev.height else setting.default['height']
        weight = str(dev.weight) if dev.weight else setting.default['weight']
        steplen = str(dev.steplen) if dev.steplen else setting.default['steplen']
        if dev.name:
            j = 0
            name = ''
            for i in unicode(dev.name):
                if i.isalpha():
                    j += 1
                else:
                    j += 2
                if j > 8:
                    break
                name += i.encode('utf8')
        else:
            name = setting.default['name'].encode('utf8')
        sendtodev(dev.imei, 'S45', [age, height, steplen, weight, sex, '|' + name + '|'])


@api.route('/addbaby', methods=['POST'])
@validate_form(forms.addbaby)
@environmentSetup()
def addbaby():
    relate = g.form.relate.data
    babyphone = g.form.babyphone.data
    userphone_new = g.form.userphone.data
    userid = g.form.userid.data
    imei = g.form.imei.data
    portrait = g.form.portrait.data
    name = g.form.name.data
    age = g.form.age.data
    height = g.form.height.data
    weight = g.form.weight.data
    sex = g.form.sex.data
    steplen = g.form.steplen.data
    birthday = g.form.birthday.data
    if not getuserdevRelate(relate):
        return ajax.failed(ajax.relateno)
    else:
        relate = UserDevRelate.objects(value=relate).get()
    # 转换关系值 "father" 为关系对象 <UserDevRelate father>
    try:
        user = User.objects(id=userid).get()
        userphone_modify = False
        userphone_old = False
        if userphone_new and (userphone_new != user.phone):
            userphone_modify = True
            userphone_old = user.phone
            # user.phone 有可能为空
            user.phone = userphone_new
            user.save()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    try:
        dev = Device.objects(imei=imei).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    try:
        # 用户与宝贝已有关系
        MyUserDev = UserDev.objects(user=userid, dev=imei).get()
        if MyUserDev.type != 'admin':
            # 用户为普通成员
            return ajax.failed(ajax.needadmin)
        if not babyphone:
            return ajax.failed(ajax.params_error)

        # 检测关系冲突
        # relatelist = []
        # userlist   = []
        # for u in User.objects(id__in=dev.family):
        #     relatelist.append(u.relateInfo)
        #     userlist.append(u.id)
        # if g.form.relate.data != user.relateInfo and g.form.relate.data in relatelist:
        #     return ajax.failed(ajax.hasconflict)

        # 管理员修改宝贝信息
        UpdateDeviceInfo(dev, portrait, name, age, height, weight, sex, steplen, babyphone, birthday)
        if userphone_modify or (user.phone not in dev.whitelist):
            for userdev in UserDev.objects(user=user.admin):
                if userphone_old:
                    userdev.dev.delWhiteList(userphone_old)
                userdev.dev.addWhiteList(userphone_new)

        # 更新关系
        if g.form.relate.data != user.relateInfo:
            MyUserDev.relate = relate
            MyUserDev.save()
            user.relateInfo = g.form.relate.data
            user.save()
            for userdev in UserDev.objects(user=user.admin):
                userdev.dev._freshWhiteList()

        FamilyPush(dev.family, {'type': 'babyinfomodify', 'imei': imei})
        # app需要更新宝贝列表,包含管理员
        return ajax.succed(ajax.ok)
    except UserDev.DoesNotExist:
        pass
    u_is_admin = UserDev.objects(user=user, type='admin').first()
    u_has_family = UserDev.objects(user=user).first()
    dev_has_family = UserDev.objects(dev=dev, type='admin').first()
    if dev_has_family:
        admin = dev_has_family.user
        # 宝贝已有管理员
        if u_is_admin:
            # 用户为管理员
            return ajax.failed(ajax.hasadmin, {'admin': admin.id, 'phone': admin.phone})
        elif u_has_family:
            # 用户为普通成员
            return ajax.failed(ajax.needadmin)
        else:
            # 用户为新用户
            try:
                disauth = Disauth.objects(dev=dev, user=user).get()
                disauth.phone = user.phone
                disauth.relate = relate
                disauth.time = datetime.datetime.now()
                disauth.save()
            except Disauth.DoesNotExist:
                Disauth(
                    admin=admin,
                    adminphone=admin.phone,
                    user=user,
                    userphone=user.phone,
                    dev=dev,
                    relate=relate
                ).save()

            FamilyPush([admin.id], {'type': 'newfamily'})
            # 推送管理员Mqtt,提示用户有新成员需要审核
            return ajax.succed(ajax.needauth, {'admin': admin.id, 'phone': admin.phone})
    else:
        if u_has_family and not u_is_admin:
            # 用户为普通用户
            return ajax.failed(ajax.needadmin)
        if not babyphone:
            return ajax.failed(ajax.params_error)
        # 宝贝没有管理员,添加关系
        UserDev(user=user, dev=dev, relate=relate, type='admin').save()
        Disauth.objects(user=user).delete()
        # 更新宝贝信息
        UpdateDeviceInfo(dev, portrait, name, age, height, weight, sex, steplen, babyphone, birthday)

        babylist = [ud.dev for ud in UserDev.objects(user=user)]
        familylist = list(set([ud.user for ud in UserDev.objects(dev__in=babylist)]))

        # 添加白名单
        dev.whitelist = [u.phone for u in familylist]
        if len(babylist) > 1:
            prev_ud = UserDev.objects(user=user).only('dev').first()
            dev.whitelist.extend(prev_ud.dev.whitelist)
            dev.whitelist = list(set(dev.whitelist))
        # 添加family
        dev.family = [u.id for u in familylist]
        dev.save()
        user.admin = user.id
        user.relateInfo = g.form.relate.data
        user.save()

        # 刷新白名单
        if userphone_modify or (user.phone not in dev.whitelist):
            if userphone_old:
                dev.delWhiteList(userphone_old)
            dev.addWhiteList(userphone_new)
        else:
            dev._freshWhiteList()
        sendtodev(imei, 'S99', [])
        # 管理员添加新宝贝,推送给普通成员
        family = dev.family[:]
        family.remove(user.id)
        FamilyPush(family, {'type': 'hasaddbaby', 'imei': imei})
        return ajax.succed(ajax.ok)


@api.route('/authlist', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def authlist():
    authlist = [
        {
            'userid': i.user.id,
            'imei': i.dev.imei,
            'phone': i.userphone,
            'relate': i.relate.value,
            'time': i.time
        } for i in Disauth.objects(admin=g.form.userid.data)
        ]
    return ajax.succed(ajax.ok, authlist)


@api.route('/confirmauth', methods=['POST'])
@validate_form(forms.userbaby)
@environmentSetup()
def confirmauth():
    imei = g.form.imei.data
    userid = g.form.userid.data
    try:
        disauth = Disauth.objects(dev=imei, user=userid).get()
    except Disauth.DoesNotExist:
        return ajax.succed(ajax.ok)
    try:
        user = User.objects(id=userid).get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    try:
        admin = UserDev.objects(dev=imei, type='admin').get().user
    except UserDev.DoesNotExist:
        Disauth.objects(user=user).delete()
        return ajax.failed(ajax.familyno)
    userdev = UserDev.objects(user=user).first()
    if not userdev:
        # 检测关系冲突
        # userdevlist = UserDev.objects(user=admin).only('dev')
        # relatelist = []
        # babylist = []
        # for userdev in userdevlist:
        #     babylist.append(userdev.dev.imei)
        # for userdev in UserDev.objects(dev__in=babylist):
        #     relatelist.append(userdev.relate)
        # if disauth.relate in relatelist:
        #     Disauth.objects(user=user).delete()
        #     return ajax.failed(ajax.hasconflict)
        # 关联用户与宝贝
        UserDev(user=user, dev=imei, relate=disauth.relate, type='common').save()
        a = Authresult(dev=imei, result='success')
        user.authresult.append(a)
        user.admin = admin.id
        user.relateInfo = disauth.relate.value
        user.save()
        # 用户审核结果
        for userdev in UserDev.objects(user=admin).only('dev'):
            # 刷新宝贝家庭圈
            if user.id not in userdev.dev.family:
                userdev.dev.family.append(user.id)
                userdev.dev.save()
            if userdev.dev.addWhiteList(user.phone):
                sendtodev(userdev.dev.imei, 'S99', [])
    Disauth.objects(user=user).delete()
    # 删除用户所有审核申请
    return ajax.succed(ajax.ok)


@api.route('/disavow', methods=['POST'])
@validate_form(forms.userbaby)
@environmentSetup()
def disavow():
    imei = g.form.imei.data
    userid = g.form.userid.data
    Disauth.objects(dev=imei, user=userid).delete()
    status = User.objects(id=userid).update_one(push__authresult=Authresult(dev=imei, result='failed'))
    if not status:
        return ajax.failed(ajax.userno)
    return ajax.succed(ajax.ok)


@api.route('/family', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def family():
    userdev = UserDev.objects(user=g.form.userid.data).only('dev').first()
    if not userdev:
        return ajax.failed(ajax.familyno)
    relatelist = []
    if userdev.dev.family:
        userlist = []
        for userdev in UserDev.objects(user__in=userdev.dev.family):
            if userdev.user.id not in userlist:
                relatelist.append({
                    'userid': userdev.user.id,
                    'phone': userdev.user.phone,
                    'imei': userdev.dev.imei,
                    'relate': userdev.relate.value,
                    'value': getuserdevRelate(userdev.relate.value),
                    'admin': 1 if userdev.type == 'admin' else 0
                })
                userlist.append(userdev.user.id)
    return ajax.succed(ajax.ok, relatelist)


@api.route('/delfamily', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def delfamily():
    userid = g.form.userid.data
    userdev = UserDev.objects(user=userid).first()
    if not userdev:
        return ajax.failed(ajax.familyno)
    if userdev.type == 'admin':
        return ajax.failed(ajax.disadmin)
    FamilyPush([userid], {'type': 'userhasdelete', 'userid': userid})
    userdev.delete()
    return ajax.succed(ajax.ok)


@api.route('/deldevice', methods=['POST'])
@validate_form(forms.userbaby)
@environmentSetup()
def deldevice():
    userid = g.form.userid.data
    imei = g.form.imei.data
    try:
        userdev = UserDev.objects(user=userid, dev=imei).get()
        dev = userdev.dev
    except UserDev.DoesNotExist:
        return ajax.failed(ajax.familyno)
    if userdev.type != 'admin':
        return ajax.failed(ajax.needadmin)
    FamilyPush(dev.family, {'type': 'babyhasdelete', 'imei': imei, 'name': dev.name})
    userdev.delete()
    sendtodev(imei, 'S98', [])
    return ajax.succed(ajax.ok)


@api.route('/iffamily', methods=['POST'])
@validate_form(forms.userbaby)
@environmentSetup()
def iffamily():
    user = db.w06.user.find_one({'_id': g.form.userid.data}, {'admin': 1})
    if not user:
        return ajax.failed(ajax.userno)
    babylist = [ud['dev'] for ud in db.w06.userdev.find({'user': user['admin']}, {'dev': 1})]
    if g.form.imei.data in babylist:
        status = 'yes'
    else:
        status = 'no'
    return ajax.succed(ajax.ok, {'status': status})


@api.route('/ifadmin', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def ifadmin():
    userdev = db.w06.userdev.find_one({'user': g.form.userid.data}, {'type': 1})
    if not userdev:
        return ajax.failed(ajax.familyno)
    if userdev['type'] == 'admin':
        return ajax.succed(ajax.ok, {'status': 'yes'})
    else:
        return ajax.succed(ajax.ok, {'status': 'no'})


@api.route('/babyrelate', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def babyrelate():
    userid = g.form.userid.data
    user = db.w06.user.find_one({'_id': userid}, {'admin': 1})
    if not user:
        return ajax.failed(ajax.userno)

    babylist = [ud['dev'] for ud in db.w06.userdev.find({'user': userid}, {'dev': 1})]

    relatelist = []
    for ud in db.w06.userdev.find({'user': userid}, {'dev': 1, 'relate': 1}):
        relate = ud['relate'] if ud['dev'] in babylist else 'family'
        value = getuserdevRelate(relate) if relate != 'family' else '家人'
        relatelist.append({
            'imei': ud['dev'],
            'relate': relate,
            'value': value
        })
    return ajax.succed(ajax.ok, relatelist)


@api.route('/babyinfo', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babyinfo():
    imei = g.form.imei.data
    try:
        dev = Device.objects(imei=imei).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)

    try:
        award = StarAward.objects(dev=dev, done=False).get()
    except StarAward.DoesNotExist:
        award = NoDevData()
    date = datetime.date.today()
    try:
        data = DevData.objects(dev=dev, date=date).get()
    except DevData.DoesNotExist:
        data = NoDevData()
    record = Maprecord.objects(dev=dev).order_by('-id').first()
    record = record if record else NoDevData()
    return ajax.succed(ajax.ok, {
        'portrait': dev.portrait,
        'name': dev.name,
        'phone': dev.phone,
        'star': award.star,
        'step': data.step,
        'distance': data.distance,
        'calories': data.calories,
        'locate': [
            {'lon': record.lon, 'lat': record.lat, 'address': record.address, 'hour': record.time.hour,
             'minute': record.time.minute}
        ]
    })


@api.route('/babyallinfo', methods=['POST'])
@validate_form(forms.userbaby)
@environmentSetup()
def babyallinfo():
    imei = g.form.imei.data
    userid = g.form.userid.data
    try:
        dev = Device.objects(imei=imei).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    try:
        userdev = UserDev.objects(dev=imei, user=userid).get()
        relate = userdev.relate.value
        value = getuserdevRelate(relate)
        user = userdev.user
    except UserDev.DoesNotExist:
        try:
            user = User.objects(id=userid).only('admin', 'phone').get()
        except User.DoesNotExist:
            return ajax.failed(ajax.userno)
        babylist = [baby.dev.imei for baby in UserDev.objects(user=user.admin).only('dev')]
        if imei in babylist:
            relate = 'family'
            value = '家人'
        else:
            return ajax.failed(ajax.familyno)
    return ajax.succed(ajax.ok, {
        'portrait': dev.portrait,
        'name': dev.name,
        'birthday': dev.birthday.date() if dev.birthday else '',
        'phone': dev.phone,
        'userphone': user.phone,
        'age': dev.age,
        'height': dev.height,
        'weight': dev.weight,
        'sex': dev.sex if dev.sex else setting.default['sex'],
        'steplen': dev.steplen,
        'relate': relate,
        'value': value
    })


@api.route('/babyname', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babyname():
    try:
        dev = Device.objects(imei=g.form.imei.data).only('name').get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok, {'name': dev.name})


@api.route('/babymodifyname', methods=['POST'])
@validate_form(forms.babyname)
@environmentSetup()
def babymodifyname():
    status = Device.objects(imei=g.form.imei.data).update_one(name=g.form.name.data)
    if not status:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok)


@api.route('/babyportrait', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babyportrait():
    try:
        dev = Device.objects(imei=g.form.imei.data).only('imgkey').get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok, {'portrait': '/static/baby/portrait/' + dev.imgkey + '.png'})


@api.route('/babymodifyportrait', methods=['POST'])
@validate_form(forms.babyportrait)
@environmentSetup()
def babymodifyportrait():
    try:
        dev = Device.objects(imei=g.form.imei.data).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    dev.updatePortrait(g.form.portrait.data)
    dev.save()
    return ajax.succed(ajax.ok)


@api.route('/babyage', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babyage():
    try:
        dev = Device.objects(imei=g.form.imei.data).only('age').get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok, {'age': dev.age})


@api.route('/babymodifyage', methods=['POST'])
@validate_form(forms.babyage)
@environmentSetup()
def babymodifyage():
    status = Device.objects(imei=g.form.imei.data).update_one(age=g.form.age.data)
    if not status:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok)


@api.route('/babyheight', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babyheight():
    try:
        dev = Device.objects(imei=g.form.imei.data).only('height').get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok, {'height': dev.height})


@api.route('/babymodifyheight', methods=['POST'])
@validate_form(forms.babyheight)
@environmentSetup()
def babymodifyheight():
    status = Device.objects(imei=g.form.imei.data).update_one(height=g.form.height.data)
    if not status:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok)


@api.route('/babytotalstar', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babytotalstar():
    data = StarAward.objects(dev=g.form.imei.data).sum('star')
    return ajax.succed(ajax.ok, {'totalstar': data})


@api.route('/babystar', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babystar():
    result = StarAward.objects(dev=g.form.imei.data, done=False).only('star')
    if not result:
        data = NoDevData()
    else:
        data = result[0]
        if len(result) > 1:
            for s in result[1:]:
                s.delete()
    return ajax.succed(ajax.ok, {'star': data.star})


@api.route('/babymodifystar', methods=['POST'])
@validate_form(forms.babymodifystar)
@environmentSetup()
def babymodifystar():
    imei = g.form.imei.data
    star = int(g.form.star.data) if int(g.form.star.data) >= 0 else 0
    result = StarAward.objects(dev=imei, done=False)
    if not result:
        return ajax.failed(ajax.starno)
    else:
        award = result[0]
        if len(result) > 1:
            # 数据库会有两条同样时间的记录,有可能同一时间重复插入
            for a in result[1:]:
                a.delete()
    if star >= award.target:
        award.endtime = datetime.datetime.now()
        award.star = award.target
        award.done = True
        result = sendtodev(imei, 'S50', ['0'])
        if result != OK:
            db.w06.device.update_one({'_id': imei}, {'$set': {'modified': 1}})
    else:
        award.star = star
        result = sendtodev(imei, 'S50', [str(star)])
        if result != OK:
            db.w06.device.update_one({'_id': imei}, {'$set': {'modified': 1}})
    award.save()
    return ajax.succed(ajax.ok)


@api.route('/babystartarget', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babystartarget():
    result = StarAward.objects(dev=g.form.imei.data, done=False)
    if not result:
        staraward = NoDevData()
    else:
        staraward = result[0]
        if len(result) > 1:
            for s in result[1:]:
                s.delete()
    return ajax.succed(ajax.ok, {
        'target': staraward.target,
        'award': staraward.award,
        'level1': getattr(staraward, 'level1', ''),
        'level2': getattr(staraward, 'level2', ''),
        'level3': getattr(staraward, 'level3', ''),
    })


@api.route('/babymodifystartarget', methods=['POST'])
@validate_form(forms.babystartarget)
@environmentSetup()
def babymodifystartarget():
    imei = g.form.imei.data
    try:
        staraward = StarAward.objects(dev=imei, done=False).get()
        staraward.target = g.form.target.data
        if g.form.award.data: staraward.award = g.form.award.data
        if g.form.level1.data: staraward.level1 = g.form.level1.data
        if g.form.level2.data: staraward.level2 = g.form.level2.data
        if g.form.level3.data: staraward.level3 = g.form.level3.data
        staraward.save()
    except StarAward.DoesNotExist:
        StarAward(
            dev=imei,
            target=g.form.target.data,
            award=g.form.award.data,
            level1=g.form.level1.data,
            level2=g.form.level2.data,
            level3=g.form.level3.data
        ).save()
    return ajax.succed(ajax.ok)


@api.route('/babysteptarget', methods=['POST'])
@validate_form(forms.babydata)
@environmentSetup()
def babysteptarget():
    date = g.form.date.data
    try:
        target = StepAward.objects(
            dev=g.form.imei.data,
            starttime__gte=date,
            starttime__lt=date + datetime.timedelta(days=1)
        ).only('target').get().target
    except StepAward.DoesNotExist:
        target = 0
    return ajax.succed(ajax.ok, {'target': target})


@api.route('/babymodifysteptarget', methods=['POST'])
@validate_form(forms.babysteptarget)
@environmentSetup()
def babymodifysteptarget():
    imei = g.form.imei.data
    target = g.form.target.data
    date = g.form.date.data
    if date != datetime.date.today():
        return ajax.failed(ajax.modifyno)
    try:
        stepaward = StepAward.objects(
            dev=imei,
            starttime__gte=date,
            starttime__lt=date + datetime.timedelta(days=1)
        ).get()
        try:
            data = DevData.objects(dev=imei, date=date).get()
            if data.step >= target:
                stepaward.target = target
                stepaward.endtime = datetime.datetime.now()
                stepaward.done = True
            else:
                stepaward.target = target
                stepaward.endtime = datetime.datetime.min
                stepaward.done = False
        except DevData.DoesNotExist:
            stepaward.target = target
        stepaward.save()
    except StepAward.DoesNotExist:
        StepAward(dev=imei, target=target).save()
    return ajax.succed(ajax.ok)


@api.route('/babystep', methods=['POST'])
@validate_form(forms.babydata)
@environmentSetup()
def babystep():
    try:
        step = DevData.objects(dev=g.form.imei.data, date=g.form.date.data).only('step').get().step
    except DevData.DoesNotExist:
        step = 0
    return ajax.succed(ajax.ok, {'step': step})


@api.route('/babymodifystep', methods=['POST'])
@validate_form(forms.babymodifystep)
@environmentSetup()
def babymodifystep():
    imei = g.form.imei.data
    date = g.form.date.data
    step = g.form.step.data
    if date != datetime.date.today():
        return ajax.failed(ajax.modifyno)
    try:
        dev = Device.objects(imei=imei).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    status = DevData.objects(dev=imei, date=date).update_one(step=step)
    if not status:
        DevData(dev=dev, step=step, distance=0, calories=0).save()
    try:
        stepaward = StepAward.objects(
            dev=imei,
            starttime__gte=date,
            starttime__lt=date + datetime.timedelta(days=1)
        ).get()
        if step >= stepaward.target:
            stepaward.endtime = datetime.datetime.now()
            stepaward.done = True
        else:
            stepaward.endtime = datetime.datetime.min
            stepaward.done = False
        stepaward.save()
    except StepAward.DoesNotExist:
        pass
    return ajax.succed(ajax.ok)


@api.route('/babydistance', methods=['POST'])
@validate_form(forms.babydata)
@environmentSetup()
def babydistance():
    try:
        distance = DevData.objects(dev=g.form.imei.data, date=g.form.date.data).only('distance').get().distance
    except DevData.DoesNotExist:
        distance = 0
    return ajax.succed(ajax.ok, {'distance': distance})


@api.route('/babymodifydistance', methods=['POST'])
@validate_form(forms.babymodifydistance)
@environmentSetup()
def babymodifydistance():
    imei = g.form.imei.data
    date = g.form.date.data
    distance = g.form.distance.data
    if date != datetime.date.today():
        return ajax.failed(ajax.modifyno)
    status = DevData.objects(dev=imei, date=date).update_one(distance=distance)
    if not status:
        DevData(dev=imei, step=0, distance=distance, calories=0).save()
    return ajax.succed(ajax.ok)


@api.route('/babycalories', methods=['POST'])
@validate_form(forms.babydata)
@environmentSetup()
def babycalories():
    try:
        calories = DevData.objects(dev=g.form.imei.data, date=g.form.date.data).only('calories').get().calories
    except DevData.DoesNotExist:
        calories = 0
    return ajax.succed(ajax.ok, {'calories': calories})


@api.route('/babymodifycalories', methods=['POST'])
@validate_form(forms.babymodifycalories)
@environmentSetup()
def babymodifycalories():
    imei = g.form.imei.data
    date = g.form.date.data
    calories = g.form.calories.data
    if date != datetime.date.today():
        return ajax.failed(ajax.modifyno)
    status = DevData.objects(dev=imei, date=date).update_one(calories=calories)
    if not status:
        DevData(dev=imei, step=0, distance=0, calories=calories).save()
    return ajax.succed(ajax.ok)


localDistance = setting.server['localDistance']


@api.route('/babytimelocate', methods=['POST'])
@validate_form(forms.babytimelocate)
@environmentSetup()
def babytimelocate():
    date = g.form.starttime.data
    today = datetime.datetime(date.year, date.month, date.day, 0, 0, 0)
    language = g.form.language.data if g.form.language.data else 'china'
    if language not in ('china', 'english'):
        return ajax.failed(ajax.languageno)

    result = db.w06.maprecord.find(
        {'dev': g.form.imei.data, 'time': {'$gt': today, '$lt': today + datetime.timedelta(days=1)}}).sort('_id')
    maprecord = list(result)
    # debug结果 需要迭代多次少量数据的最好一次性获取
    # maprecord [1,2,3,4,5,6,7,8,9]
    maprecordList = []
    try:
        previous = maprecord[0]
        maprecordList.append(previous)
        for record in maprecord[1:]:
            if record['useGPS'] and (not previous['useGPS']):
                maprecordList.append(record)
                continue
            distance = getDistance(record['lon'], record['lat'], previous['lon'], previous['lat'])
            if distance >= localDistance:
                if len(maprecordList) >= 50:
                    break
                maprecordList.append(record)
            else:
                record['time'] = previous['time']
            previous = record
    except IndexError:
        pass

    l = len(maprecordList)
    # maprecordList [1,3,4,6,9]
    datalist = [{
                    'lon': m['lon'],
                    'lat': m['lat'],
                    'address': m['address'],
                    'hour': '%02d' % m['time'].hour,
                    'minute': '%02d' % m['time'].minute,
                    'staytime': timeHandle(m['time'], maprecordList[i + 1]['time'],
                                           language) if i + 1 != l else timeHandle(m['time'], datetime.datetime.now(),
                                                                                   language)
                } for i, m in enumerate(maprecordList)
                ]
    return ajax.succed(ajax.ok, datalist)


@api.route('/babyImmediate', methods=['POST'])
@validate_form(forms.Immediate)
@environmentSetup()
def babyImmediate():
    imei = request.form.get('imei')
    if not imei:
        return ajax.failed(ajax.params_error)
    result = interact(imei, 'S13', [])
    if result:
        if result == NO:
            return ajax.succed(ajax.offline)
        if result == TIMEOUT:
            return ajax.succed(ajax.timeout)
        if result == OK:
            return ajax.succed(ajax.ok)
    else:
        return ajax.succed(ajax.locateno)


@api.route('/babylastlocate', methods=['POST'])
@validate_form(forms.babynowlocate)
@environmentSetup()
def babylastlocate():
    m = db.w06.maprecord.find_one({'dev': g.form.imei.data}, {'time': 1, 'lon': 1, 'lat': 1, 'address': 1},
                                  sort=[('_id', DESCENDING)])
    if not m:
        m = {'time': datetime.datetime.min, 'address': '', 'lon': 0, 'lat': 0}
    language = g.form.language.data if g.form.language.data else 'china'
    if language not in ('china', 'english'):
        return ajax.failed(ajax.languageno)
    return ajax.succed(ajax.ok, {
        'lon': m['lon'],
        'lat': m['lat'],
        'address': m['address'],
        'time': timeHandle(m['time'], datetime.datetime.now(), language),
        'ultratime': m['time']
    })


gpsRadius = setting.locate['GPS']
lbsRadius = setting.locate['LBS']


@api.route('/babynowlocate', methods=['POST'])
@validate_form(forms.babynowlocate)
@environmentSetup()
def babynowlocate():
    imei = g.form.imei.data
    result = sendtodev(imei, 'S13', [])
    status = 'yes' if result != NO else 'no'
    m = db.w06.maprecord.find_one({'dev': imei}, {'time': 1, 'lon': 1, 'lat': 1, 'address': 1, 'useGPS': 1},
                                  sort=[('_id', DESCENDING)])
    if not m:
        m = {'time': datetime.datetime.min, 'address': '', 'lon': 0, 'lat': 0}
    language = g.form.language.data if g.form.language.data else 'china'
    if language not in ('china', 'english'):
        return ajax.failed(ajax.languageno)
    return ajax.succed(ajax.ok, {
        'lon': m['lon'],
        'lat': m['lat'],
        'address': m['address'],
        'time': timeHandle(m['time'], datetime.datetime.now(), language),
        'ultratime': m['time'],
        'status': status,
        'radius': gpsRadius if m['useGPS'] else lbsRadius,
    })


@api.route('/allbabynowlocate', methods=['POST'])
@validate_form(forms.allbabynowlocate)
@environmentSetup()
def allbabynowlocate():
    userid = g.form.userid.data
    language = g.form.language.data if g.form.language.data else 'china'
    if language not in ('china', 'english'):
        return ajax.failed(ajax.languageno)
    result = UserDev.objects(user=userid)
    if not result:
        return ajax.failed(ajax.familyno)
    babylist = [userdev.dev for userdev in result]
    maplist = []
    for baby in babylist:
        m = Maprecord.objects(dev=baby).order_by('-id').first()
        m = m if m else NoDevData()
        maplist.append({
            'imei': baby.imei,
            'name': baby.name,
            'lon': m.lon,
            'lat': m.lat,
            'address': m.address,
            'time': timeHandle(m.time, datetime.datetime.now(), language),
        })
    return ajax.succed(ajax.ok, maplist)


@api.route('/babyalllocate', methods=['POST'])
@environmentSetup()
def babyalllocate():
    try:
        imei = request.form['imei']
        date = datetime.datetime.strptime(request.form['starttime'], '%Y-%m-%d %H:%M:%S')
        today = datetime.datetime(date.year, date.month, date.day, 0, 0, 0)
    except:
        return ajax.failed(ajax.params_error)
    result = list(
        db.w06.maprecord.find({'dev': imei, 'time': {'$gt': today, '$lt': today + datetime.timedelta(days=1)}}).sort(
            '_id', DESCENDING))
    return ajax.succed(ajax.ok, [{
                                     'lon': m['lon'],
                                     'lat': m['lat'],
                                     'address': m['address'],
                                     'type': 'GPS' if m['useGPS'] else 'LBS',
                                     'hour': '%02d' % m['time'].hour,
                                     'minute': '%02d' % m['time'].minute,
                                 } for m in result])


@api.route('/babystatus', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def babystatus():
    imei = g.form.imei.data
    result = findimei(imei)
    if result == NO:
        return ajax.succed(ajax.ok, {'status': 'offline'})
    return ajax.succed(ajax.ok, {'status': 'online'})


@api.route('/addsaferegion', methods=['POST'])
@validate_form(forms.addsaferegion)
@environmentSetup()
def addsaferegion():
    imei = g.form.imei.data
    region = Saferegion(
        name=g.form.name.data,
        address=g.form.address.data,
        radius=g.form.radius.data,
        lon=g.form.lon.data,
        lat=g.form.lat.data
    )
    status = Device.objects(imei=imei).update_one(push__saferegion=region)
    if not status:
        return ajax.failed(ajax.devno)
    sendtodev(imei, 'S99', [])
    return ajax.succed(ajax.ok, {'saferegionid': region.id})


@api.route('/modifysaferegion', methods=['POST'])
@validate_form(forms.modifysaferegion)
@environmentSetup()
def modifysaferegion():
    imei = g.form.data['imei']
    safeid = g.form.saferegionid.data
    try:
        dev = Device.objects(imei=imei).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    region = None
    for i in dev.saferegion:
        if i.id == safeid:
            region = i
            break
    if not region:
        return ajax.failed(ajax.saferegionno)
    if g.form.data['name']:
        region.name = g.form.data['name']
    if g.form.data['address']:
        region.address = g.form.data['address']
    if g.form.data['radius']:
        region.radius = g.form.data['radius']
    if g.form.data['lon']:
        region.lon = g.form.data['lon']
    if g.form.data['lat']:
        region.lat = g.form.data['lat']
    dev.save()
    sendtodev(imei, 'S99', [])
    return ajax.succed(ajax.ok)


@api.route('/deletesaferegion', methods=['POST'])
@validate_form(forms.saferegion)
@environmentSetup()
def deletesaferegion():
    imei = g.form.imei.data
    safeid = g.form.saferegionid.data
    try:
        dev = Device.objects(imei=imei, saferegion__id=safeid).get()
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    region = None
    for i in dev.saferegion:
        if i.id == safeid:
            region = i
            break
    if not region:
        return ajax.failed(ajax.saferegionno)
    dev.saferegion.remove(region)
    dev.save()
    sendtodev(imei, 'S99', [])
    return ajax.succed(ajax.ok)


@api.route('/saferegion', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def saferegion():
    dev = db.w06.device.find_one({'_id': g.form.imei.data}, {'saferegion': 1})
    if not dev:
        return ajax.failed(ajax.devno)
    if dev.get('saferegion'):
        regionlist = [
            {'id': i['id'], 'name': i['name'], 'address': i['address'], 'radius': i['radius'], 'lon': i['lon'],
             'lat': i['lat']} for i in
            dev.get('saferegion')
            ]
    else:
        regionlist = []
    return ajax.succed(ajax.ok, regionlist)


@api.route('/babysaferegion', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def babysaferegion():
    result = db.w06.user.find({'_id': g.form.userid.data}, {'admin': 1})
    try:
        userAdmin = result[0]['admin']
    except IndexError:
        return ajax.failed(ajax.userno)
    imeilist = [ud['dev'] for ud in db.w06.userdev.find({'user': userAdmin}, {'dev': 1})]
    regionlist = []
    babylist = [dev for dev in db.w06.device.find({'_id': {'$in': imeilist}}, {'_id': 1, 'name': 1, 'saferegion': 1})]
    for dev in babylist:
        if dev.get('saferegion'):
            for region in dev['saferegion']:
                regionlist.append({
                    'id': region['id'],
                    'imei': dev['_id'],
                    'babyname': dev['name'],
                    'safename': region['name'],
                    'address': region['address'],
                    'radius': region['radius'],
                    'lon': region['lon'],
                    'lat': region['lat']
                })
    return ajax.succed(ajax.ok, regionlist)


@api.route('/localremind', methods=['POST'])
def localremind():
    """
    localremind 系列接口兼容旧版APP,弃用
    """
    return ajax.succed(ajax.ok, [])


@api.route('/babylocalremind', methods=['POST'])
def babylocalremind():
    return ajax.succed(ajax.ok, [])


@api.route('/localremindcenter', methods=['POST'])
def localremindcenter():
    return ajax.succed(ajax.ok, [])


@api.route('/babylocalremindcenter', methods=['POST'])
def babylocalremindcenter():
    return ajax.succed(ajax.ok, [])


@api.route('/getsos', methods=['POST'])
@validate_form(forms.getsos)
@environmentSetup()
def getsos():
    imei = g.form.imei.data
    page = int(g.form.page.data) if g.form.page.data > 0 else 0
    num = int(g.form.num.data) if g.form.num.data > 0 else 20
    month = datetime.datetime.strptime(g.form.month.data, '%Y-%m') if g.form.month.data else None
    date = g.form.date.data if not month else None
    if month:
        result = db.w06.sos.find(
            {'dev': imei, 'time': {'$gte': month, '$lt': month + datetime.timedelta(days=30)}}).sort('_id',
                                                                                                     DESCENDING).limit(
            num).skip(page * num)
    elif date:
        result = db.w06.sos.find({'dev': imei, 'time': {'$gte': date, '$lt': date + datetime.timedelta(days=1)}}).sort(
            '_id', DESCENDING).limit(num).skip(page * num)
    else:
        result = db.w06.sos.find({'dev': imei}).sort('_id', DESCENDING).limit(num).skip(page * num)
    soslist = [
        {
            'address': i['address'],
            'lon': i['lon'],
            'lat': i['lat'],
            'date': i['time'].date(),
            'month': i['time'].month,
            'hour': i['time'].hour,
            'minute': i['time'].minute
        } for i in result
        ]
    return ajax.succed(ajax.ok, soslist)


@api.route('/messagecenter', methods=['POST'])
@validate_form(forms.babypagenum)
@environmentSetup()
def messagecenter():
    page = int(g.form.page.data) if g.form.page.data > 0 else 0
    num = int(g.form.num.data) if g.form.num.data > 0 else 10
    messagelist = []
    for mess in db.w06.messagecenter.find({'dev': g.form.imei.data}).sort('_id', DESCENDING).limit(num).skip(
                    page * num):
        value = ''
        if mess['type'] != 'dial':
            value = mess['value'] if mess['type'] == 'voltage' else json.loads(mess['value'])
        messagelist.append({
            'type': mess['type'],
            'value': value,
            'date': mess['time'].date(),
            'hour': mess['time'].hour,
            'minute': mess['time'].minute,
        })
    return ajax.succed(ajax.ok, messagelist)


@api.route('/uploadlocate', methods=['POST'])
@validate_form(forms.uploadlocate)
@environmentSetup()
def uploadlocate():
    Apprecord(
        user=g.form.userid.data,
        dev=g.form.imei.data,
        address=g.form.address.data,
        lon=g.form.lon.data,
        lat=g.form.lat.data,
    ).save()
    return ajax.succed(ajax.ok)


@api.route('/sendmessage', methods=['POST'])
@validate_form(forms.sendmessage)
@environmentSetup()
def sendmessage():
    userid = g.form.userid.data
    imei = g.form.imei.data
    try:
        user = User.objects(id=userid).only('admin', 'relateInfo').get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    babylist = [ud.dev for ud in UserDev.objects(user=user.admin).only('dev')]

    m = Message(
        sender=str(userid),
        dev=imei,
        content=g.form.content.data,
        audioid=g.form.audioid.data,
        audiolen=g.form.audiolen.data,
        type='user'
    )
    m.save()

    userlist = list(set([ud.user.id for ud in UserDev.objects(dev__in=babylist)]))
    userlist.remove(userid)
    gevent.spawn(sendmessagetodev, babylist, g.form.content)

    FamilyPush(userlist, {
        'type': 'newmessage',
        'data': {
            'id': str(userid),
            'type': 'user',
            'portrait': '/admin/static/relate/' + user.relateInfo + '.png',
            'audioid': g.form.audioid.data,
            'audiolen': g.form.audiolen.data,
            'time': m.time,
        }
    })
    return ajax.succed(ajax.ok)


def sendmessagetodev(babylist, content):
    audioIO = StringIO.StringIO()
    audioIO.write(content.data.decode('base64'))
    for dev in babylist:
        audioIO.seek(0)
        result = reduceAudio(dev.imei, audioIO)
        if result != OK:
            audioIO.seek(0)
            audio = DeviceAudio()
            audio.content.put(audioIO)
            if len(dev.audio) < 3:
                dev.audio.append(audio)
            else:
                a = dev.audio.pop(0)
                a.content.delete()
                dev.audio.append(audio)
            dev.save()


@api.route('/getmessage', methods=['POST'])
@validate_form(forms.getmessage)
@environmentSetup()
def getmessage():
    page = int(g.form.page.data) if g.form.page.data > 0 else 0
    num = int(g.form.num.data) if g.form.num.data > 0 else 20
    result = db.w06.user.find({'_id': g.form.userid.data}, {'admin': 1})
    try:
        userAdmin = result[0]['admin']
    except IndexError:
        return ajax.failed(ajax.userno)
    imeilist = [userdev['dev'] for userdev in db.w06.userdev.find({'user': userAdmin}, {'dev': 1})]
    if g.form.time.data:
        result = db.w06.message.find({'dev': {'$in': imeilist}, 'time': {'$gt': g.form.time.data}},
                                     {'content': 0}).sort(
            '_id', DESCENDING).limit(num).skip(page * num)
    else:
        result = db.w06.message.find({'dev': {'$in': imeilist}}, {'content': 0}).sort('_id', DESCENDING).limit(
            num).skip(page * num)
    result = list(result)
    # 将迭代器转换成list用于二次遍历
    babylist = []
    userlist = []
    for mess in result:
        if mess['type'] == 'baby':
            babylist.append(mess['sender'])
        else:
            mess['sender'] = int(mess['sender'])
            userlist.append(mess['sender'])
    babydict = {}
    for baby in db.w06.device.find({'_id': {'$in': babylist}}, {'_id': 1, 'imgkey': 1}):
        babydict[baby['_id']] = '/static/baby/portrait/' + baby['imgkey'] + '.png' if baby.get('imgkey') else ''
    userdict = {}
    for user in db.w06.user.find({'_id': {'$in': userlist}}, {'_id': 1, 'relateInfo': 1}):
        userdict[user['_id']] = '/admin/static/relate/' + user['relateInfo'] + '.png' if user.get('relateInfo') else ''

    message = [{
                   'id': mess['sender'],
                   'audioid': mess['audioid'],
                   'audiolen': mess['audiolen'],
                   'portrait': babydict[mess['sender']] if mess['type'] == 'baby' else userdict[mess['sender']],
                   'type': mess['type'],
                   'time': mess['time']
               } for mess in result]
    return ajax.succed(ajax.ok, message)


@api.route('/setmessagereadtime', methods=['POST'])
@validate_form(forms.setmessagereadtime)
@environmentSetup()
def setmessagereadtime():
    status = User.objects(id=g.form.userid.data).update_one(mesageReadTime=g.form.time.data)
    if not status:
        return ajax.failed(ajax.userno)
    return ajax.succed(ajax.ok)


@api.route('/lastmessagereadtime', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def lastmessagereadtime():
    try:
        user = User.objects(id=g.form.userid.data).only('mesageReadTime').get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    return ajax.succed(ajax.ok, {'time': user.mesageReadTime})


@api.route('/getaudio', methods=['POST'])
@validate_form(forms.getaudio)
@environmentSetup()
def getaudio():
    m = db.w06.message.find_one({'sender': g.form.userid.data, 'audioid': g.form.audioid.data}, {'content': 1})
    if not m:
        content = ''
    else:
        content = m['content']
    return ajax.succed(ajax.ok, {'content': content})


@api.route('/getsilent', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def getsilent():
    dev = db.w06.device.find_one({'_id': g.form.imei.data}, {'silent': 1})
    if not dev:
        return ajax.failed(ajax.devno)
    silentlist = [
        {
            'num': i['num'],
            'weekday': i['weekday'].split(','),
            'starttime': i['starttime'].strftime('%H:%M'),
            'endtime': i['endtime'].strftime('%H:%M'),
            'status': 1 if i['status'] else 0,
        } for i in dev['silent']
        ] if dev['silent'] else []
    return ajax.succed(ajax.ok, silentlist)


def V1_0_9_silent(imei, weekday, starttime_s, endtime_s):
    weekdaystr = ['1' if str(i) in weekday else '0' for i in range(1, 8)]
    weekdaystr = ''.join(weekdaystr)
    result = sendtodev(imei, 'S41', ['on'])
    params = ['%s-%s|%s;|;|' % (starttime_s, endtime_s, weekdaystr)]
    if result == OK:
        result = interact(imei, 'S9', params)
        if result != OK:
            return ajax.failed(ajax.timeout)
        else:
            return ajax.succed(ajax.ok)
    else:
        db.w06.device.update_one({'_id': imei}, {
            '$push': {'jobbox': {
                '$each': [{'instruct': 'S41', 'params': ['on']},
                          {'instruct': 'S9', 'params': params, 'time': datetime.datetime.now()}]}}})


def V1_0_67_silent(imei, num, daylist, starttime, endtime, weekday):
    addScheduler(
        func=SchedulerSilent_on,
        jobid='%s_%s_on' % (imei, num),
        args=(imei,),
        weekday=daylist,
        hour=starttime.hour,
        minute=starttime.minute
    )
    addScheduler(
        func=SchedulerSilent_off,
        jobid='%s_%s_off' % (imei, num),
        args=(imei,),
        weekday=daylist,
        hour=endtime.hour,
        minute=endtime.minute
    )
    now = datetime.datetime.now()
    test_time = datetime.datetime(starttime.year, starttime.month, starttime.day, now.hour, now.minute)
    if str(now.weekday() + 1) in weekday and (endtime > test_time > starttime):
        sendtodev(imei, 'S41', ['on'])


@api.route('/setsilent', methods=['POST'])
@validate_form(forms.setsilent)
@environmentSetup()
def setsilent():
    imei = g.form.imei.data
    num = g.form.num.data
    status = g.form.status.data
    if num > 3:
        return ajax.failed(ajax.silnummax)

    try:
        starttime_s = g.form.starttime.data if g.form.starttime.data != '24:00' else '23:59'
        starttime = datetime.datetime.strptime(starttime_s, '%H:%M')
        endtime_s = g.form.endtime.data if g.form.endtime.data != '24:00' else '23:59'
        endtime = datetime.datetime.strptime(endtime_s, '%H:%M')
        if starttime >= endtime:
            return ajax.failed(ajax.params_error)
        weekday = g.form.weekday.data.strip(',').split(',')
        weekday = list(set(weekday))
        weekday.sort()
        # weekday = ['1','2','3','4','5]
        daylist = [WeekDay[i] for i in weekday]
        daylist = ','.join(daylist)
    except (KeyError, ValueError):
        return ajax.failed(ajax.params_error)

    if not num:
        try:
            dev = Device.objects(imei=imei).only('silent').get()
        except Device.DoesNoteExist:
            return ajax.failed(ajax.devno)
        if dev.silent:
            num = len(dev.silent)
        else:
            num = 0
        if num >= 3:
            return ajax.failed(ajax.silnummax)
        s = Silent(
            num=num + 1,
            weekday=','.join(weekday),
            starttime=starttime,
            endtime=endtime,
            status=True if status else False
        )
        Device.objects(imei=imei).update_one(push__silent=s)
        if status and dev.version == 'V1.0.9':
            V1_0_9_silent(imei, weekday, starttime_s, endtime_s)
        elif status:
            V1_0_67_silent(imei, num, daylist, starttime, endtime, weekday)
        else:
            delScheduler('%s_%s_on' % (imei, num))
            delScheduler('%s_%s_off' % (imei, num))
            sendtodev(imei, 'S41', ['off'])
    else:
        try:
            dev = Device.objects(imei=imei).get()
        except Device.DoesNotExist:
            return ajax.failed(ajax.devno)
        new_s = Silent(
            num=num,
            weekday=','.join(weekday),
            starttime=starttime,
            endtime=endtime,
            status=True if status else False
        )
        if dev.silent:
            # 修改或添加腕表静音设置
            old_s = None
            for s in dev.silent:
                if s.num == num:
                    old_s = s
                    break
            if old_s:
                dev.silent.remove(old_s)
            dev.silent.append(new_s)
            dev.silent.sort(lambda x, y: x.num - y.num)
            dev.save()
            if status and dev.version == 'V1.0.9':
                V1_0_9_silent(imei, weekday, starttime_s, endtime_s)
            elif status:
                V1_0_67_silent(imei, num, daylist, starttime, endtime, weekday)
            else:
                delScheduler('%s_%s_on' % (imei, num))
                delScheduler('%s_%s_off' % (imei, num))
                sendtodev(imei, 'S41', ['off'])
        elif num != 1:
            return ajax.failed(ajax.params_error)
        else:
            # 添加第一组静音
            if not Device.objects(imei=imei).update_one(push__silent=new_s):
                return ajax.failed(ajax.devno)
            elif status and dev.version == 'V1.0.9':
                V1_0_9_silent(imei, weekday, starttime_s, endtime_s)
            elif status:
                V1_0_67_silent(imei, num, daylist, starttime, endtime, weekday)
            else:
                delScheduler('%s_%s_on' % (imei, num))
                delScheduler('%s_%s_off' % (imei, num))
                sendtodev(imei, 'S41', ['off'])
    return ajax.succed(ajax.ok)


@api.route('/delsilent', methods=['POST'])
@validate_form(forms.delsilent)
@environmentSetup()
def delsilent():
    imei = g.form.imei.data
    num = g.form.num.data
    try:
        dev = Device.objects(imei=imei, silent__match={'num': num}).get()
        for silent in dev.silent:
            if silent.num == num:
                dev.silent.remove(silent)
                break
        dev.save()
        delScheduler('%s_%s_on' % (imei, num))
        delScheduler('%s_%s_off' % (imei, num))
    except Device.DoesNotExist:
        pass
    return ajax.succed(ajax.ok)


@api.route('/silent', methods=['POST'])
@validate_form(forms.silent)
@environmentSetup()
def silent():
    imei = g.form.imei.data
    operate = g.form.operate.data
    if operate not in ('on', 'off'):
        return ajax.failed(ajax.params_error)
    if operate == 'on':
        result = interact(imei, 'S41', ['on'])
    else:
        result = interact(imei, 'S41', ['off'])
    if result == OK:
        silentoption = True if operate == 'on' else False
        status = Device.objects(imei=imei).update_one(silentoption=silentoption)
        if status:
            return ajax.succed(ajax.ok)
        else:
            return ajax.failed(ajax.devno)
    elif result == NO:
        return ajax.failed(ajax.offline)
    elif result == TIMEOUT:
        return ajax.failed(ajax.timeout)
    else:
        logger.error(imei + ' silent ' + operate + ' get ' + repr(result))
        return ajax.failed(ajax.serverno)


@api.route('/getsilentstatus', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def getsilentstatus():
    dev = db.w06.device.find_one({'_id': g.form.imei.data}, {'silentoption': 1})
    if not dev:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok, {'status': 'on' if dev.get('silentoption') else 'off'})


@api.route('/settimezone', methods=['POST'])
@validate_form(forms.settimezone)
@environmentSetup()
def settimezone():
    imei = g.form.imei.data
    try:
        timezone = int(g.form.timezone.data)
    except ValueError:
        return ajax.failed(ajax.params_error)
    result = interact(imei, 'S8', [str(timezone)])
    if result == OK:
        status = Device.objects(imei=imei).update_one(timezone=timezone)
        if status:
            return ajax.succed(ajax.ok)
        else:
            return ajax.failed(ajax.devno)
    elif result == NO:
        return ajax.failed(ajax.offline)
    elif result == TIMEOUT:
        return ajax.failed(ajax.timeout)
    else:
        return ajax.failed(ajax.serverno)


@api.route('/gettimezone', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def gettimezone():
    dev = db.w06.message.find_one({'imei': g.form.imei.data}, {'timezone': 1})
    if not dev:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok, {'timezone': dev.get('timezone', 8)})


@api.route('/setmonitor', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def setmonitor():
    imei = g.form.imei.data
    result = interact(imei, 'S39', [])
    if result == OK:
        MessageCenter(dev=imei, type='dial', value='').save()
        return ajax.succed(ajax.ok)
    return ajax.failed(ajax.monitorno)


@api.route('/delmonitor', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def delmonitor():
    imei = g.form.imei.data
    sendtodev(imei, 'S40', [])
    return ajax.succed(ajax.ok)


@api.route('/getwhitelist', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def getwhitelist():
    userdev = UserDev.objects(user=g.form.userid.data).only('dev').first()
    if not userdev:
        return ajax.failed(ajax.familyno)
    return ajax.succed(ajax.ok, userdev.dev.whitelist)


@api.route('/addwhitelist', methods=['POST'])
@validate_form(forms.userphone)
@environmentSetup()
def addwhitelist():
    try:
        user = User.objects(id=g.form.userid.data).only('admin').get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    for userdev in UserDev.objects(user=user.admin).only('dev'):
        userdev.dev.addWhiteList(g.form.phone.data)
    return ajax.succed(ajax.ok)


@api.route('/delwhitelist', methods=['POST'])
@validate_form(forms.userphone)
@environmentSetup()
def delwhitelist():
    phone = g.form.phone.data
    try:
        user = User.objects(id=g.form.userid.data).only('admin').get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    Babylist = UserDev.objects(user=user.admin).only('dev')
    if not Babylist:
        return ajax.failed(ajax.familyno)
    familyphone = [user.phone for user in User.objects(id__in=Babylist[0].dev.family)]
    if phone not in familyphone:
        for userdev in Babylist:
            userdev.dev.delWhiteList(phone)
    return ajax.succed(ajax.ok)


@api.route('/familyphone', methods=['POST'])
@validate_form(forms.userid)
@environmentSetup()
def familyphone():
    userid = g.form.userid.data
    try:
        user = User.objects(id=userid).only('id', 'admin').get()
    except User.DoesNotExist:
        return ajax.failed(ajax.userno)
    userdev = UserDev.objects(user=userid).only('dev').first()
    if not userdev:
        return ajax.failed(ajax.familyno)
    not_admin = 1 if user.id != user.admin else 0
    white = userdev.dev.whitelist[:]
    familyphone = [u.phone for u in User.objects(id__in=userdev.dev.family)]
    sos = [phone for phone in white if phone in familyphone][:4]
    whitelist = [{'phone': phone, 'erasable': 0 if (phone in familyphone) or not_admin else 1} for phone in white]
    return ajax.succed(ajax.ok, {'white': whitelist, 'sos': sos, 'dial': sos})


@api.route('/setlocalinterval', methods=['POST'])
@validate_form(forms.setlocalinterval)
@environmentSetup()
def setlocalinterval():
    imei = g.form.imei.data
    minute = g.form.minute.data
    status = Device.objects(imei=imei).update_one(localintervalminute=minute)
    if not status:
        return ajax.failed(ajax.devno)
    try:
        result = sendtodev(imei, 'S16', ['00:00:00', '23:59:59', str(minute)])
        if result != OK:
            db.w06.device.update_one({'_id': imei}, {'$set': {'modified': 1}})
        return ajax.succed(ajax.ok)
    except:
        return ajax.failed(ajax.intervalno)


@api.route('/getlocalinterval', methods=['POST'])
@validate_form(forms.baby)
@environmentSetup()
def getlocalinterval():
    try:
        localintervalminute = Device.objects(imei=g.form.imei.data).only(
            'localintervalminute').get().localintervalminute
    except Device.DoesNotExist:
        return ajax.failed(ajax.devno)
    return ajax.succed(ajax.ok, {'minute': localintervalminute})


@api.route('/feedback', methods=['POST'])
@validate_form(forms.feedback)
@environmentSetup()
def feedback():
    Feedback(user=g.form.userid.data, content=g.form.content.data).save()
    return ajax.succed(ajax.ok)


@api.route('/logger/<imei>', methods=['GET', 'POST'])
def devlogger(imei):
    if len(imei) != 15:
        return abort(404)
    return render_template('logger', imei=imei)


@api.route('/logging/<imei>', methods=['GET', 'POST'])
def devlogging(imei):
    if request.form.get('time', None):
        t = datetime.datetime.fromtimestamp(int(request.form['time']))
        data = [{'event': l.event, 'value': l.value, 'time': l.time} for l in
                Loger.objects(model='server', ident=imei, time__gt=t).order_by('-id')]
    else:
        data = [{'event': l.event, 'value': l.value, 'time': l.time} for l in
                Loger.objects(model='server', ident=imei).order_by('-id').limit(10)]
    return json.dumps(data)
